// Date and Time (日期和时间) 示例
// 演示 Pascal 中日期和时间处理的各种用法
program p_43_date_and_time;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils,      // 系统工具单元
  DateUtils;     // 日期时间工具单元

// 显示当前日期和时间
procedure DisplayCurrentDateTime;
var
  currentDateTime: TDateTime;
begin
  WriteLn('1. 当前日期和时间:');
  currentDateTime := Now;
  
  WriteLn('  Now: ', DateTimeToStr(currentDateTime));
  WriteLn('  Date: ', DateToStr(Date));
  WriteLn('  Time: ', TimeToStr(Time));
  WriteLn('  格式化显示:');
  WriteLn('    短格式: ', FormatDateTime('d/m/yy h:nn', currentDateTime));
  WriteLn('    长格式: ', FormatDateTime('dddd, dd mmmm yyyy hh:nn:ss', currentDateTime));
  WriteLn('    自定义: ', FormatDateTime('yyyy-mm-dd hh:nn:ss', currentDateTime));
end;

// 日期时间格式化示例
procedure DateTimeFormattingExamples;
var
  dt: TDateTime;
begin
  WriteLn('2. 日期时间格式化示例:');
  dt := EncodeDateTime(2025, 9, 25, 14, 30, 45, 123);
  
  WriteLn('  原始日期时间: ', DateTimeToStr(dt));
  WriteLn('  不同格式化选项:');
  WriteLn('    短日期: ', FormatDateTime('d/m/yy', dt));
  WriteLn('    长日期: ', FormatDateTime('dd/mm/yyyy', dt));
  WriteLn('    完整日期: ', FormatDateTime('dddd, dd mmmm yyyy', dt));
  WriteLn('    24小时制时间: ', FormatDateTime('hh:nn:ss', dt));
  WriteLn('    12小时制时间: ', FormatDateTime('hh:nn:ss am/pm', dt));
  WriteLn('    带毫秒: ', FormatDateTime('hh:nn:ss.zzz', dt));
  WriteLn('    ISO格式: ', FormatDateTime('yyyy-mm-dd hh:nn:ss', dt));
  WriteLn('    仅时间: ', FormatDateTime('hh:nn', dt));
  WriteLn('    仅日期: ', FormatDateTime('dd/mm/yyyy', dt));
end;

// 日期时间计算示例
procedure DateTimeCalculationExamples;
var
  startDate, endDate: TDateTime;
  daysDiff, hoursDiff, minutesDiff: Double;
begin
  WriteLn('3. 日期时间计算示例:');
  startDate := EncodeDateTime(2025, 1, 1, 0, 0, 0, 0);
  endDate := Now;
  
  WriteLn('  起始日期: ', DateTimeToStr(startDate));
  WriteLn('  结束日期: ', DateTimeToStr(endDate));
  
  // 计算差值
  daysDiff := DaysBetween(endDate, startDate);
  hoursDiff := HoursBetween(endDate, startDate);
  minutesDiff := MinutesBetween(endDate, startDate);
  
  WriteLn('  时间差:');
  WriteLn('    天数: ', daysDiff:0:0);
  WriteLn('    小时数: ', hoursDiff:0:0);
  WriteLn('    分钟数: ', minutesDiff:0:0);
  
  // 日期加减
  WriteLn('  日期加减:');
  WriteLn('    当前日期加7天: ', DateTimeToStr(IncDay(endDate, 7)));
  WriteLn('    当前日期减30天: ', DateTimeToStr(IncDay(endDate, -30)));
  WriteLn('    当前日期加1个月: ', DateTimeToStr(IncMonth(endDate, 1)));
  WriteLn('    当前日期加1年: ', DateTimeToStr(IncYear(endDate, 1)));
  WriteLn('    月末日期: ', DateTimeToStr(EndOfTheMonth(endDate)));
  WriteLn('    年末日期: ', DateTimeToStr(EndOfTheYear(endDate)));
end;

// 日期时间构造和解析示例
procedure DateTimeConstructionAndParsing;
var
  constructedDate: TDateTime;
  year, month, day: Word;
  hour, minute, second, msec: Word;
begin
  WriteLn('4. 日期时间构造和解析示例:');
  
  // 构造日期时间
  constructedDate := EncodeDateTime(2025, 12, 25, 15, 30, 45, 500);
  WriteLn('  构造的日期时间: ', DateTimeToStr(constructedDate));
  
  // 解析日期
  DecodeDate(constructedDate, year, month, day);
  WriteLn('  解析日期: ', year, '-', month:0:0, '-', day:0:0);
  
  // 解析时间
  DecodeTime(constructedDate, hour, minute, second, msec);
  WriteLn('  解析时间: ', hour:0:0, ':', minute:0:0, ':', second:0:0, '.', msec:0:0);
  
  // 从字符串解析日期
  try
    constructedDate := StrToDateTime('2025-06-15 10:30:00');
    WriteLn('  从字符串解析: ', DateTimeToStr(constructedDate));
  except
    on E: Exception do
      WriteLn('  解析错误: ', E.Message);
  end;
end;

// 时间间隔计算示例
procedure TimeIntervalCalculation;
var
  startDateTime, endDateTime: TDateTime;
  elapsedTime: TDateTime;
begin
  WriteLn('5. 时间间隔计算示例:');
  startDateTime := EncodeDateTime(2025, 9, 25, 10, 0, 0, 0);
  endDateTime := EncodeDateTime(2025, 9, 25, 14, 30, 45, 123);
  
  WriteLn('  开始时间: ', DateTimeToStr(startDateTime));
  WriteLn('  结束时间: ', DateTimeToStr(endDateTime));
  
  // 计算经过的时间
  elapsedTime := endDateTime - startDateTime;
  
  WriteLn('  经过时间:');
  WriteLn('    总天数: ', elapsedTime:0:6);
  WriteLn('    总小时数: ', elapsedTime * 24:0:2);
  WriteLn('    总分钟数: ', elapsedTime * 24 * 60:0:2);
  WriteLn('    总秒数: ', elapsedTime * 24 * 60 * 60:0:2);
  
  // 使用专门的函数计算
  WriteLn('  使用函数计算:');
  WriteLn('    小时差: ', HoursBetween(endDateTime, startDateTime));
  WriteLn('    分钟差: ', MinutesBetween(endDateTime, startDateTime));
  WriteLn('    秒差: ', SecondsBetween(endDateTime, startDateTime));
end;

// 日期时间比较示例
procedure DateTimeComparison;
var
  date1, date2: TDateTime;
begin
  WriteLn('6. 日期时间比较示例:');
  date1 := EncodeDate(2025, 6, 15);
  date2 := EncodeDate(2025, 9, 25);
  
  WriteLn('  日期1: ', DateToStr(date1));
  WriteLn('  日期2: ', DateToStr(date2));
  
  if date1 < date2 then
    WriteLn('  日期1早于日期2')
  else if date1 > date2 then
    WriteLn('  日期1晚于日期2')
  else
    WriteLn('  日期1等于日期2');
  
  if IsSameDay(date1, date2) then
    WriteLn('  是同一天')
  else
    WriteLn('  不是同一天');
  
  if IsInLeapYear(date1) then
    WriteLn('  日期1所在年份是闰年')
  else
    WriteLn('  日期1所在年份不是闰年');
  
  WriteLn('  日期1是这一年的第', DayOfTheYear(date1), '天');
  WriteLn('  日期1是星期', WeekDayName(DayOfTheWeek(date1)));
end;

// 程序主入口
begin
  WriteLn('=== Pascal 日期和时间示例 ===');
  WriteLn;
  
  // 1. 显示当前日期和时间
  DisplayCurrentDateTime;
  
  WriteLn;
  
  // 2. 日期时间格式化示例
  DateTimeFormattingExamples;
  
  WriteLn;
  
  // 3. 日期时间计算示例
  DateTimeCalculationExamples;
  
  WriteLn;
  
  // 4. 日期时间构造和解析示例
  DateTimeConstructionAndParsing;
  
  WriteLn;
  
  // 5. 时间间隔计算示例
  TimeIntervalCalculation;
  
  WriteLn;
  
  // 6. 日期时间比较示例
  DateTimeComparison;
  
  WriteLn;
  WriteLn('演示了 Pascal 中日期和时间处理的各种用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.